package com.cnswhy.cloud.server.core.channel.hcpay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cnswhy.cloud.common.core.exception.BizException;
import com.cnswhy.cloud.common.core.utils.*;
import com.cnswhy.cloud.server.core.channel.hcpay.constant.Config;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.Key;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author:Lajiao
 * @Date:2014年8月21日
 * @Time:下午12:42:13
 * @Description:请求基础类
 */
@Slf4j
public class SdkRequest {
    public static final String RSA_ALGORITHM = "RSA";

    public static String requestActions(String action, String data, String orgNo, String merNo, String key, String privateKey) throws BizException {
        String encryptkey = "1234567890123456";
        String dataStr = AESTool.encrypt(data, encryptkey);
        StringBuilder signBuffer = new StringBuilder();
        signBuffer.append(dataStr);
        String sign = Md5Utils.getMd5(signBuffer.toString() + key);
        log.info(sign);
        String rsaEncryptkey = null;
        try {
            rsaEncryptkey = Base64.encode(RSAUtils.encryptByPublicKey(encryptkey.getBytes("UTF-8"), Config.publicKey));
        } catch (Exception e) {
            throw new BizException(0001, "加密失败");
        }
        log.info("rsaEncryptkey：{}", rsaEncryptkey);
        Map<String, String> parameters = new HashMap<>();
        parameters.put("version", Config.version);
        parameters.put("branchCode", orgNo);
        parameters.put("merchId", merNo);
        parameters.put("requestName", action);
        parameters.put("data", dataStr);
        parameters.put("encryptkey", rsaEncryptkey);
        parameters.put("sign", sign);
        log.info("－－－－－－请求数据－－－－－－－");
        String requestContent = createRequest(parameters);
        log.info("－－－－－－请求数据－－－－－－－{}:{}", Config.payUrl, requestContent);
        String resultBuffer = doPost(Config.payUrl, requestContent);
        String result = "";
        if (StringUtils.isBlank(resultBuffer)) {
            if ("subBindCardConfirm".equals(action)) {
                result = "{\"code\":\"0001\",\"message\":\"请求超时\"}";
                log.info("－－－－－－绑卡返回数据超时,置为失败－－－－－－－");
            } else {
                result = "{\"code\":\"0000\",\"data\":{\"respDesc\":\"交易处理中\",\"orderStatus\":\"01\",\"respCode\":\"0100\"},\"message\":\"成功\"}";
            }
            log.info("－－－－－－返回数据超时,置为处理中－－－－－－－");
        } else {
            log.info("－－－－－－返回数据－－－－－－－:{}", resultBuffer.toString());
            //System.out.println(resultBuffer.toString());
            JSONObject jsonObject = JSON.parseObject(resultBuffer.toString());
            String rtnData = jsonObject.getString("data");
            String rtnEncryptkey = jsonObject.getString("encryptkey");
            if (StringUtils.isEmpty(rtnData) || StringUtils.isEmpty(rtnEncryptkey)) {
                log.error("rtnData or rtnEncryptkey is null");
                if (StringUtils.isNotBlank(jsonObject.getString("code")) && StringUtils.isNotBlank(jsonObject.getString("msg"))) {
                    throw new BizException(0001, jsonObject.getString("msg"));
                }
                return rtnData;
            }
            byte[] aesKey = new byte[0];
            try {
                aesKey = RSAUtils.decryptByPrivateKey(Base64.decode(rtnEncryptkey), privateKey);
            } catch (Exception e) {
                throw new BizException(0001, "解密失败");
            }
            //byte[] aesKey = RSAUtils.decryptByPublicKey(Base64.decode(rtnEncryptkey), Config.privateKey);
            result = AESTool.decrypt(rtnData, new String(aesKey));
        }

        log.info("请求结果：" + result);
        return result;

    }

    public static String createRequest(Map<String, String> parm) {
        StringBuffer rtn = new StringBuffer();
        for (String s : parm.keySet()) {
            try {
                if (parm.get(s) != null) {
                    rtn.append(s).append("=").append(URLEncoder.encode(parm.get(s), "UTF-8")).append("&");
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return rtn.toString();
    }

    public static String doPost(String url, String content) {
        /**
         * 发送请求
         */
        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();
        String tempLine = null;
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            HttpURLConnection httpURLConnection = (HttpURLConnection) connection;

            httpURLConnection.setDoOutput(true);
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setRequestProperty("Accept-Charset", "utf-8");
            httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            httpURLConnection.setRequestProperty("Content-Length", String.valueOf(content.length()));

            outputStream = httpURLConnection.getOutputStream();
            outputStreamWriter = new OutputStreamWriter(outputStream);
            outputStreamWriter.write(content);
            outputStreamWriter.flush();

            inputStream = httpURLConnection.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream);
            reader = new BufferedReader(inputStreamReader);
            while ((tempLine = reader.readLine()) != null) {
                resultBuffer.append(tempLine);
            }
            return resultBuffer.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (outputStreamWriter != null) {
                    outputStreamWriter.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
                if (reader != null) {
                    reader.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 加密
     *
     * @param source
     * @param key
     * @return
     * @throws Exception
     */
    public byte[] encrypt(byte[] source, Key key) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] resultBytes = cipher.doFinal(source);
        return resultBytes;
    }

    /**
     * 解密
     *
     * @param source
     * @param key
     * @return
     * @throws Exception
     */
    public byte[] decrypt(byte[] source, Key key) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] resultBytes = cipher.doFinal(source);
        return resultBytes;
    }
}
